<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 改变this指向 的三种方法 ：
        // this 不要关注this的定义 需要关注this的调用；
        // 一、call ： function.call(this,参数1,参数2..);
        // "use strict";
        // function fn(a,b){
        //     console.log("fn里的this是：",this,a,b);
        // }

        // 1.直接调用 指向window  2. 严格模式下调用指向undefined 3.实例化调用是指向实力化对象  4.对象.fn调用会指向对象；
        // fn();
        // var res = new fn();
        // var obj = {
        //     fn:fn,
        //     name:"张三"
        // }
        // // obj.fn();
        // var myfn = obj.fn;
        // myfn();
        // 直接调用
        // fn(1,2);
        // 调用的同时 改变 fn函数里的this指向 ；
        // var obj = {name:123};
        // fn.call(obj,1,2);

        // 注意 ： call 一般会改对象 为 函数里的this；
        // 如果 call 的是undefined 和 null 那么 函数内的this会 指向window
        // 如果 call的是简单数据类型  那么函数里的this会指向 ,简单数据类型的对象形式；
        // fn.call({name:"hello"},1,2);
        // fn.call(null,1,2);
        // fn.call(123,1,2);


        // 二、apply 方法   function.apply(this,[参数1,参数2,参数3]);

        // function fn(a,b){
        //     console.log(this,a,b);
        // }

        // // fn.call({name:"hello"},1,2);
        // fn.apply({name:"hello"},[1,2]);

        // apply 更方便的接收数组类型的不定参数 ；
        // function fn2(){  // 需要接收fn1的所有参数 ；fn1的参数 不恒定；
        //     console.log("fn2:",this,arguments); // obj的this
        // }

        // function fn1(){
        //     var obj = {
        //         name:"hello"
        //     }
        //     console.log(arguments);

        //     // fn2.call(obj);
        //     fn2.apply(obj,arguments);
        // }

        // fn1(1,2,3,4);


        // 三 、bind ： function.bind(this)(参数1,参数2,参数3); 
        // 需要执行2次 ，调用两次小括号 ；

        // function fn(a,b){
        //     console.log("fn的this是",this,a,b);
        // }

        // var obj = {
        //     name:123
        // }
        // fn.bind(obj)(1,2);  // 延迟执行 ；

        function myfn(){
            console.log("打印了",this);
        }

        // document.onclick = myfn;
        // document.onclick = myfn.call({name:123});
        document.onclick = function(){
            myfn.call({name:123});
        }

        // document.onclick = myfn.bind({name:123});



        /* 
            总结 ： 
                如果 传入的是null 、undefined  那么函数会指向 window
                如果传入的是简单数据类型那么函数会把简单数据类型包装成对象；
               call ： 参数需要一个个的传入
               apply： 参数如要一个数组 
               bind ： 需要执行2次；
        
        
        */


    </script>
</body>
</html>